/**
 * Copyright 2019-2020 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <gtest/gtest.h>
#include <nlohmann/json.hpp>

#define protected public
#define private public
#include <graph/tensor.h>
#include "graph_optimizer/op_compiler/tbe_json_parse.h"
#include "common/fe_utils.h"
#include "common/fe_log.h"
#include "graph/ge_tensor.h"
#undef protected
#undef private

using namespace std;
using namespace fe;
using namespace ge;
using namespace nlohmann;


static Status ParseParams(const google::protobuf::Message* op_src, ge::Operator& op_dest)
{
    return fe::SUCCESS;
}

static Status InferShapeAndType(vector<ge::TensorDesc>& v_output_desc)
{
    return fe::SUCCESS;
}

static Status UpdateOpDesc(ge::Operator&)
{
    return fe::SUCCESS;
}

static Status GetWorkspaceSize(const ge::Operator&, std::vector<int64_t>&)
{
    return fe::SUCCESS;
}


static Status BuildTeBin(TbeJsonInfo& te_bin_info)
{
    return fe::SUCCESS;
}

static Status BuildTeBin1(string json_file_name, TbeJsonInfo& te_bin_info)
{
    te_bin_info.bin_file_path = "./air/test/engines/nneng/stub/cce_reductionLayer_1_10_float16__1_SUMSQ_1_0.o";
    te_bin_info.json_file_path = "air/test/engines/nneng/ut/testcase/fusion_engine/op_compiler/json/"+json_file_name;
    return fe::SUCCESS;
}

static Status BuildTeBin2(TbeJsonInfo& te_bin_info)
{
    te_bin_info.bin_file_path = "./air/test/engines/nneng/stub/cce_reductionLayer_1_10_float16__1_SUMSQ_1_0.o";
    te_bin_info.json_file_path = "air/test/engines/nneng/ut/testcase/fusion_engine/op_compiler/json/cce_reductionLayer_1_10_float16__1_SUMSQ_1_with_so.json";
    return fe::SUCCESS;
}

static Status BuildTeBin5(TbeJsonInfo& te_bin_info)
{
    te_bin_info.bin_file_path = "./air/test/engines/nneng/stub/cce_reductionLayer_1_10_float16__1_SUMSQ_1_0.o";
    te_bin_info.json_file_path = "air/test/engines/nneng/ut/testcase/fusion_engine/op_compiler/json/cce_reduction_layer_1_10_float16__1_SUMSQ_1_0_null.json";
    return fe::SUCCESS;
}

static Status BuildTeBin6(TbeJsonInfo& te_bin_info)
{
    te_bin_info.bin_file_path = "./air/test/engines/nneng/stub/cce_reductionLayer_1_10_float16__1_SUMSQ_1_0.o";
    te_bin_info.json_file_path = "air/test/engines/nneng/ut/testcase/fusion_engine/op_compiler/json/cce_reduction_layer_1_10_float16__1_SUMSQ_1_0_error2.json";
    return fe::SUCCESS;
}

static Status BuildTeBin7(TbeJsonInfo& te_bin_info)
{
    te_bin_info.bin_file_path = "./air/test/engines/nneng/stub/cce_reduction_layer_1_10_float16__1_SUMSQ_1_0_no_exist.o";
    te_bin_info.json_file_path = "air/test/engines/nneng/ut/testcase/fusion_engine/op_compiler/json/cce_reductionLayer_1_10_float16__1_SUMSQ_1_0.json";
    return fe::SUCCESS;
}

static Status BuildTeBin8(TbeJsonInfo& te_bin_info)
{
    te_bin_info.bin_file_path = "./air/test/engines/nneng/stub/cce_reductionLayer_1_10_float16__1_SUMSQ_1_0.o";
    te_bin_info.json_file_path = "air/test/engines/nneng/ut/testcase/fusion_engine/op_compiler/json/cce_reduction_layer_1_10_float16__1_SUMSQ_1_0_error3.json";
    return fe::SUCCESS;
}

static Status BuildTeBin9(TbeJsonInfo& te_bin_info)
{
    te_bin_info.bin_file_path = "./air/test/engines/nneng/stub/cce_reductionLayer_1_10_float16__1_SUMSQ_1_0.o";
    te_bin_info.json_file_path = "air/test/engines/nneng/ut/testcase/fusion_engine/op_compiler/json/cce_reduction_layer_1_10_float16__1_SUMSQ_1_0_noworkspace.json";
    return fe::SUCCESS;
}

static Status BuildTeBin10(TbeJsonInfo& te_bin_info)
{
    te_bin_info.bin_file_path = "./air/test/engines/nneng/stub/cce_reductionLayer_1_10_float16__1_SUMSQ_1_0.o";
    te_bin_info.json_file_path = "air/test/engines/nneng/ut/testcase/fusion_engine/op_compiler/json/cce_reduction_layer_1_10_float16__1_SUMSQ_1_0_error4.json";
    return fe::SUCCESS;
}

static Status BuildTeBin11(TbeJsonInfo& te_bin_info)
{
    te_bin_info.bin_file_path = "./air/test/engines/nneng/stub/cce_reductionLayer_1_10_float16__1_SUMSQ_1_0.o";
    te_bin_info.json_file_path = "air/test/engines/nneng/ut/testcase/fusion_engine/op_compiler/json/cce_reduction_layer_1_10_float16__1_SUMSQ_1_0_error5.json";
    return fe::SUCCESS;
}

static Status BuildTeBin12(TbeJsonInfo& te_bin_info)
{
    te_bin_info.json_file_path = "air/test/engines/nneng/ut/testcase/fusion_engine/op_compiler/json/cce_reduction_layer_1_10_float16__1_SUMSQ_1_0_not_exist.json";
    return fe::SUCCESS;
}

static Status BuildTeBin13(TbeJsonInfo& te_bin_info)
{
    te_bin_info.bin_file_path = "./air/test/engines/nneng/stub/cce_reductionLayer_1_10_float16__1_SUMSQ_1_0.o";
    te_bin_info.json_file_path = "air/test/engines/nneng/config/fe_config/atomic_test_parameters.json";
    return fe::SUCCESS;
}

static Status BuildTeBin14(TbeJsonInfo& te_bin_info)
{
    te_bin_info.bin_file_path = "./air/test/engines/nneng/stub/cce_reductionLayer_1_10_float16__1_SUMSQ_1_0.o";
    te_bin_info.json_file_path = "air/test/engines/nneng/config/fe_config/atomic_test_parameters_no_workspace.json";
    return fe::SUCCESS;
}

static Status BuildTeBin15(TbeJsonInfo& te_bin_info)
{
    te_bin_info.bin_file_path = "./air/test/engines/nneng/stub/cce_reductionLayer_1_10_float16__1_SUMSQ_1_0.o";
    te_bin_info.json_file_path = "air/test/engines/nneng/config/fe_config/atomic_test_parameters_workspace_not_equal.json";
    return fe::SUCCESS;
}

static Status BuildTeBin16(TbeJsonInfo& te_bin_info)
{
    te_bin_info.bin_file_path = "./air/test/engines/nneng/stub/cce_reductionLayer_1_10_float16__1_SUMSQ_1_0.o";
    te_bin_info.json_file_path = "air/test/engines/nneng/config/fe_config/atomic_test_parameters_size_not_equal.json";
    return fe::SUCCESS;
}

static Status BuildTeBin18(TbeJsonInfo& te_bin_info)
{
    te_bin_info.json_file_path = "air/test/engines/nneng/ut/testcase/fusion_engine/op_compiler/json/te_conv2d_compress.json";
    return fe::SUCCESS;
}

static Status BuildTeBinCoreTypeAIV(TbeJsonInfo& te_bin_info)
{
  te_bin_info.json_file_path = "air/test/engines/nneng/ut/testcase/fusion_engine/op_compiler/json/te_conv2d_compress_core_type.json";
  return fe::SUCCESS;
}

static Status BuildTeBinCoreTypeAIVFail(TbeJsonInfo& te_bin_info)
{
  te_bin_info.json_file_path = "air/test/engines/nneng/ut/testcase/fusion_engine/op_compiler/json/te_conv2d_compress_core_type_fail.json";
  return fe::SUCCESS;
}
class UTEST_FE_TBE_JSON_PARSER: public testing::Test
{
protected:
    void SetUp()
    {

    }

    void TearDown()
    {
    }
public:

};

TEST_F(UTEST_FE_TBE_JSON_PARSER, case_not_exist_bin_failed)
{
    ge::OpDescPtr op_desc = std::make_shared<ge::OpDesc>();

    OpDescPtr op_desc_ptr = make_shared<ge::OpDesc>();

    TbeJsonFileParse json_file_parse(op_desc_ptr);
    TbeJsonInfo info;
    BuildTeBin12(info);

    Status ret = json_file_parse.PackageTvmJsonInfo(info);

    //3. result expected
    EXPECT_EQ(ret, fe::FAILED);
}

TEST_F(UTEST_FE_TBE_JSON_PARSER, case_json_format_error_failed)
{
    ge::OpDescPtr op_desc = std::make_shared<ge::OpDesc>();

    OpDescPtr op_desc_ptr = make_shared<ge::OpDesc>();

    TbeJsonFileParse json_file_parse(op_desc_ptr);
    TbeJsonInfo info;
    BuildTeBin10(info);
    Status ret = json_file_parse.PackageTvmJsonInfo(info);

    //3. result expected
    EXPECT_EQ(ret, fe::FAILED);
}

TEST_F(UTEST_FE_TBE_JSON_PARSER, case_json_bin_error2)
{

    ge::OpDescPtr op_desc = std::make_shared<ge::OpDesc>();

    OpDescPtr op_desc_ptr = make_shared<ge::OpDesc>();

    TbeJsonFileParse json_file_parse(op_desc_ptr);

    //char* buffer = nullptr;
    //int length = 0;
    string file_name = "./air/test/engines/nneng/stub/emptyfile";

    vector<char> buffer;
    Status ret = json_file_parse.ReadBytesFromBinaryFile(file_name.c_str(), buffer);

    //3. result expected
    EXPECT_EQ(ret, fe::FAILED);
}
